package news.utils.parse;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.namespace.QName;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import news.utils.util.LoggerUtils;
import news.utils.util.ObjectUtils;

import org.apache.commons.lang.StringUtils;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.DomSerializer;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
  
public class BaseParse {  
      
    public static String getNodeValue(final Object result) {  
        if (result != null) {  
            if (result instanceof NodeList) {  
                final StringBuffer stringBuffer = new StringBuffer();  
                NodeList nodeList = (NodeList) result;  
                for (int i = 0; i < nodeList.getLength(); i++) {  
                    Node node = nodeList.item(i);  
                    stringBuffer.append(node.getNodeValue().trim().replaceAll("\n", "") + " ");  
                }  
                return stringBuffer.toString();  
            }else {  
                LoggerUtils.warn("Result Is Not A Node Or NodeList");  
            }  
        }else {  
            LoggerUtils.warn("Result Is Null");  
        }  
        return null;  
    }  
      
    public static <T> T parseObject(Class<T> clazz,String htmlPage, Map<String, String> itemMap) throws Exception {  
        HtmlCleaner hcCleaner = new HtmlCleaner();  
        TagNode tagNode = hcCleaner.clean(htmlPage);  
        Document dom = new DomSerializer(new CleanerProperties()).createDOM(tagNode);  
        Iterator<Entry<String, String>> iterator = itemMap.entrySet().iterator();  
        XPath xPath = XPathFactory.newInstance().newXPath();  
        Map<Object, Object> resultMap = new HashMap<>();  
        while (iterator.hasNext()) {  
            Entry<String, String> entry = iterator.next();  
            String key = entry.getKey();  
            String xpathStr = entry.getValue();  
            if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(xpathStr)) {  
                Object result = xPath.evaluate(xpathStr, dom, XPathConstants.NODESET);  
                resultMap.put(key, getNodeValue(result));  
            }else {  
                LoggerUtils.warn("Key Or Xpath Is Blank!");  
            }  
        }  
        T t = clazz.newInstance();  
        ObjectUtils.copyWithMap(t, resultMap);  
        return t;  
    }  
  
    public static Object parse(String htmlPage,String xPathStr,QName qName) throws Exception{  
        Object result = null;  
        if (StringUtils.isNotBlank(htmlPage) && StringUtils.isNotBlank(xPathStr)) {  
            HtmlCleaner hcCleaner = new HtmlCleaner();  
            TagNode tagNode = hcCleaner.clean(htmlPage);  
            Document dom = new DomSerializer(new CleanerProperties()).createDOM(tagNode);  
            XPath xPath = XPathFactory.newInstance().newXPath();  
            result = xPath.evaluate(xPathStr, dom, qName);  
        }else {  
            LoggerUtils.warn("Key Or Xpath Is Blank!");  
        }  
        return result;  
    }  
  
}  